{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Portfolio Optimization using cvxpy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Install cvxpy and other libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "!{sys.executable} -m pip install -r requirements.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cvxpy as cvx\n",
    "import numpy as np\n",
    "import quiz_tests"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Quiz Solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cvxpy as cvx\n",
    "import numpy as np\n",
    "\n",
    "def optimize_twoasset_portfolio(varA, varB, rAB):\n",
    "    \"\"\"Create a function that takes in the variance of Stock A, the variance of\n",
    "    Stock B, and the correlation between Stocks A and B as arguments and returns \n",
    "    the vector of optimal weights\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    varA : float\n",
    "        The variance of Stock A.\n",
    "        \n",
    "    varB : float\n",
    "        The variance of Stock B.    \n",
    "        \n",
    "    rAB : float\n",
    "        The correlation between Stocks A and B.\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    x : np.ndarray\n",
    "        A 2-element numpy ndarray containing the weights on Stocks A and B,\n",
    "        [x_A, x_B], that minimize the portfolio variance.\n",
    "    \n",
    "    \"\"\"\n",
    "    # TODO: Use cvxpy to determine the weights on the assets in a 2-asset\n",
    "    # portfolio that minimize portfolio variance.\n",
    "    cov = np.sqrt(varA)*np.sqrt(varB)*rAB\n",
    "    x = cvx.Variable(2)\n",
    "    P = np.array([[varA, cov],[cov, varB]])\n",
    "    objective = cvx.Minimize(cvx.quad_form(x,P))\n",
    "    constraints = [sum(x)==1]\n",
    "    problem = cvx.Problem(objective, constraints)\n",
    "    min_value = problem.solve()\n",
    "    xA,xB = x.value\n",
    "    \n",
    "    return xA, xB\n",
    "\n",
    "quiz_tests.test_optimize_twoasset_portfolio(optimize_twoasset_portfolio)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"Test run optimize_twoasset_portfolio().\"\"\"\n",
    "xA,xB = optimize_twoasset_portfolio(0.1, 0.05, 0.25)\n",
    "print(\"Weight on Stock A: {:.6f}\".format(xA))\n",
    "print(\"Weight on Stock B: {:.6f}\".format(xB))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
